import unittest

# TODO: fix this to work with the new data types
from interfaces.metric import *
from interfaces.physical_topology import *
from aggmon.importers.ganglia_xml import GangliaXMLMetricImporter, GangliaXMLPhysicalTopologyImporter


GANGLIA_XML = """\
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!DOCTYPE GANGLIA_XML [
   <!ELEMENT GANGLIA_XML (GRID|CLUSTER|HOST)*>
      <!ATTLIST GANGLIA_XML VERSION CDATA #REQUIRED>
      <!ATTLIST GANGLIA_XML SOURCE CDATA #REQUIRED>
   <!ELEMENT GRID (CLUSTER | GRID | HOSTS | METRICS)*>
      <!ATTLIST GRID NAME CDATA #REQUIRED>
      <!ATTLIST GRID AUTHORITY CDATA #REQUIRED>
      <!ATTLIST GRID LOCALTIME CDATA #IMPLIED>
   <!ELEMENT CLUSTER (HOST | HOSTS | METRICS)*>
      <!ATTLIST CLUSTER NAME CDATA #REQUIRED>
      <!ATTLIST CLUSTER OWNER CDATA #IMPLIED>
      <!ATTLIST CLUSTER LATLONG CDATA #IMPLIED>
      <!ATTLIST CLUSTER URL CDATA #IMPLIED>
      <!ATTLIST CLUSTER LOCALTIME CDATA #REQUIRED>
   <!ELEMENT HOST (METRIC)*>
      <!ATTLIST HOST NAME CDATA #REQUIRED>
      <!ATTLIST HOST IP CDATA #REQUIRED>
      <!ATTLIST HOST LOCATION CDATA #IMPLIED>
      <!ATTLIST HOST REPORTED CDATA #REQUIRED>
      <!ATTLIST HOST TN CDATA #IMPLIED>
      <!ATTLIST HOST TMAX CDATA #IMPLIED>
      <!ATTLIST HOST DMAX CDATA #IMPLIED>
      <!ATTLIST HOST GMOND_STARTED CDATA #IMPLIED>
   <!ELEMENT METRIC EMPTY>
      <!ATTLIST METRIC NAME CDATA #REQUIRED>
      <!ATTLIST METRIC VAL CDATA #REQUIRED>
      <!ATTLIST METRIC TYPE (string | int8 | uint8 | int16 | uint16 | int32 | uint32 | float | double | timestamp) #REQUIRED>
      <!ATTLIST METRIC UNITS CDATA #IMPLIED>
      <!ATTLIST METRIC TN CDATA #IMPLIED>
      <!ATTLIST METRIC TMAX CDATA #IMPLIED>
      <!ATTLIST METRIC DMAX CDATA #IMPLIED>
      <!ATTLIST METRIC SLOPE (zero | positive | negative | both | unspecified) #IMPLIED>
      <!ATTLIST METRIC SOURCE (gmond | gmetric) #REQUIRED>
   <!ELEMENT HOSTS EMPTY>
      <!ATTLIST HOSTS UP CDATA #REQUIRED>
      <!ATTLIST HOSTS DOWN CDATA #REQUIRED>
      <!ATTLIST HOSTS SOURCE (gmond | gmetric | gmetad) #REQUIRED>
   <!ELEMENT METRICS EMPTY>
      <!ATTLIST METRICS NAME CDATA #REQUIRED>
      <!ATTLIST METRICS SUM CDATA #REQUIRED>
      <!ATTLIST METRICS NUM CDATA #REQUIRED>
      <!ATTLIST METRICS TYPE (string | int8 | uint8 | int16 | uint16 | int32 | uint32 | float | double | timestamp) #REQUIRED>
      <!ATTLIST METRICS UNITS CDATA #IMPLIED>
      <!ATTLIST METRICS SLOPE (zero | positive | negative | both | unspecified) #IMPLIED>
      <!ATTLIST METRICS SOURCE (gmond | gmetric) #REQUIRED>
]>
<GANGLIA_XML VERSION="3.0.5" SOURCE="gmond">
<CLUSTER NAME="LustreSrv" LOCALTIME="1250243899" OWNER="OSCAR" LATLONG="unspecified" URL="unspecified">
<HOST NAME="lxt1.stg.hpce.tld" IP="192.168.50.158" REPORTED="1250243896" TN="2" TMAX="20" DMAX="0" LOCATION="unspecified" GMOND_STARTED="0">
</HOST>
<HOST NAME="dmds1.stg.hpce.tld" IP="192.168.50.130" REPORTED="1250243897" TN="1" TMAX="20" DMAX="0" LOCATION="unspecified" GMOND_STARTED="1249987937">
<METRIC NAME="disk_total" VAL="153.650" TYPE="double" UNITS="GB" TN="2160" TMAX="1200" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_speed" VAL="1995" TYPE="uint32" UNITS="MHz" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="part_max_used" VAL="77.0" TYPE="float" UNITS="%" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="swap_total" VAL="8385848" TYPE="uint32" UNITS="KB" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="os_name" VAL="Linux" TYPE="string" UNITS="" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="cpu_user" VAL="0.2" TYPE="float" UNITS="%" TN="10" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_system" VAL="0.1" TYPE="float" UNITS="%" TN="10" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_aidle" VAL="99.5" TYPE="float" UNITS="%" TN="10" TMAX="3800" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="load_five" VAL="0.03" TYPE="float" UNITS=" " TN="0" TMAX="325" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="proc_run" VAL="0" TYPE="uint32" UNITS=" " TN="200" TMAX="950" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_free" VAL="6618184" TYPE="uint32" UNITS="KB" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_buffers" VAL="236856" TYPE="uint32" UNITS="KB" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="swap_free" VAL="8385848" TYPE="uint32" UNITS="KB" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="bytes_in" VAL="2582.35" TYPE="float" UNITS="bytes/sec" TN="40" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="pkts_out" VAL="20.85" TYPE="float" UNITS="packets/sec" TN="40" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_num" VAL="8" TYPE="uint16" UNITS="CPUs" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="disk_free" VAL="108.876" TYPE="double" UNITS="GB" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_total" VAL="8177524" TYPE="uint32" UNITS="KB" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="cpu_wio" VAL="0.0" TYPE="float" UNITS="%" TN="10" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="boottime" VAL="1249987875" TYPE="uint32" UNITS="s" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="machine_type" VAL="x86_64" TYPE="string" UNITS="" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="os_release" VAL="2.6.18-92.1.26.el5_lustre.1.6.7" TYPE="string" UNITS="" TN="360" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="cpu_nice" VAL="0.0" TYPE="float" UNITS="%" TN="10" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_idle" VAL="99.7" TYPE="float" UNITS="%" TN="10" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="load_one" VAL="0.01" TYPE="float" UNITS=" " TN="0" TMAX="70" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="load_fifteen" VAL="0.00" TYPE="float" UNITS=" " TN="0" TMAX="950" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="proc_total" VAL="332" TYPE="uint32" UNITS=" " TN="200" TMAX="950" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_shared" VAL="0" TYPE="uint32" UNITS="KB" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_cached" VAL="920512" TYPE="uint32" UNITS="KB" TN="60" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="gexec" VAL="OFF" TYPE="string" UNITS="" TN="60" TMAX="300" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="bytes_out" VAL="8870.10" TYPE="float" UNITS="bytes/sec" TN="40" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="pkts_in" VAL="23.50" TYPE="float" UNITS="packets/sec" TN="40" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="swap_in" VAL="0" TYPE="uint32" UNITS="pages/minute" TN="19" TMAX="60" DMAX="0" SLOPE="both" SOURCE="gmetric"/>
<METRIC NAME="swap_out" VAL="0" TYPE="uint32" UNITS="pages/minute" TN="19" TMAX="60" DMAX="0" SLOPE="both" SOURCE="gmetric"/>
<METRIC NAME="lbug" VAL="0" TYPE="uint32" UNITS="LBUGs" TN="7" TMAX="60" DMAX="0" SLOPE="both" SOURCE="gmetric"/>
</HOST>
<HOST NAME="dmds2.stg.hpce.tld" IP="192.168.50.131" REPORTED="1250243881" TN="18" TMAX="20" DMAX="0" LOCATION="unspecified" GMOND_STARTED="1250184160">
<METRIC NAME="disk_total" VAL="170.561" TYPE="double" UNITS="GB" TN="2136" TMAX="1200" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_speed" VAL="1995" TYPE="uint32" UNITS="MHz" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="part_max_used" VAL="77.9" TYPE="float" UNITS="%" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="swap_total" VAL="8385848" TYPE="uint32" UNITS="KB" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="os_name" VAL="Linux" TYPE="string" UNITS="" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="cpu_user" VAL="0.3" TYPE="float" UNITS="%" TN="76" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_system" VAL="0.3" TYPE="float" UNITS="%" TN="76" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_aidle" VAL="99.4" TYPE="float" UNITS="%" TN="76" TMAX="3800" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="load_five" VAL="0.02" TYPE="float" UNITS=" " TN="66" TMAX="325" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="proc_run" VAL="0" TYPE="uint32" UNITS=" " TN="216" TMAX="950" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_free" VAL="7313176" TYPE="uint32" UNITS="KB" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_buffers" VAL="182708" TYPE="uint32" UNITS="KB" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="swap_free" VAL="8385848" TYPE="uint32" UNITS="KB" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="bytes_in" VAL="2206.77" TYPE="float" UNITS="bytes/sec" TN="16" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="pkts_out" VAL="14.85" TYPE="float" UNITS="packets/sec" TN="16" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_num" VAL="8" TYPE="uint16" UNITS="CPUs" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="disk_free" VAL="135.519" TYPE="double" UNITS="GB" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_total" VAL="8177788" TYPE="uint32" UNITS="KB" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="cpu_wio" VAL="0.0" TYPE="float" UNITS="%" TN="76" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="boottime" VAL="1250184099" TYPE="uint32" UNITS="s" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="machine_type" VAL="x86_64" TYPE="string" UNITS="" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="os_release" VAL="2.6.18-128.2.1.el5.NECLustre02l" TYPE="string" UNITS="" TN="936" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="cpu_nice" VAL="0.0" TYPE="float" UNITS="%" TN="76" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="cpu_idle" VAL="99.4" TYPE="float" UNITS="%" TN="76" TMAX="90" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="load_one" VAL="0.00" TYPE="float" UNITS=" " TN="66" TMAX="70" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="load_fifteen" VAL="0.00" TYPE="float" UNITS=" " TN="66" TMAX="950" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="proc_total" VAL="254" TYPE="uint32" UNITS=" " TN="216" TMAX="950" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_shared" VAL="0" TYPE="uint32" UNITS="KB" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="mem_cached" VAL="370512" TYPE="uint32" UNITS="KB" TN="76" TMAX="180" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="gexec" VAL="OFF" TYPE="string" UNITS="" TN="36" TMAX="300" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="bytes_out" VAL="1983.55" TYPE="float" UNITS="bytes/sec" TN="16" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="pkts_in" VAL="16.88" TYPE="float" UNITS="packets/sec" TN="16" TMAX="300" DMAX="0" SLOPE="both" SOURCE="gmond"/>
<METRIC NAME="swap_in" VAL="0" TYPE="uint32" UNITS="pages/minute" TN="27" TMAX="60" DMAX="0" SLOPE="both" SOURCE="gmetric"/>
<METRIC NAME="swap_out" VAL="0" TYPE="uint32" UNITS="pages/minute" TN="27" TMAX="60" DMAX="0" SLOPE="both" SOURCE="gmetric"/>
<METRIC NAME="lbug" VAL="0" TYPE="uint32" UNITS="LBUGs" TN="25" TMAX="60" DMAX="0" SLOPE="both" SOURCE="gmetric"/>
</HOST>
</CLUSTER>
</GANGLIA_XML>
"""


class GangliaXMLMetricImporterTest(unittest.TestCase):
    def runTest( self ):
        importer = GangliaXMLMetricImporter()
        requests = [request for request in importer._parseGangliaXML( GANGLIA_XML )]
        assert len( requests ) == 124
        for request in requests:
            assert isinstance( request, addMetricRequest ) or \
                   isinstance( request, addMetricValueRequest )


class GangliaXMLPhysicalTopologyImporterTest(unittest.TestCase):
    def runTest( self ):
        importer = GangliaXMLPhysicalTopologyImporter()
        requests = [request for request in importer._parseGangliaXML( GANGLIA_XML )]
        assert len( requests ) == 5
        assert isinstance( requests[0], addClusterRequest )
        assert isinstance( requests[1], addRackRequest )
        for request_i in xrange( 2, len( requests ) ):
            assert isinstance( requests[request_i], addHostRequest )


suite = unittest.TestSuite()
suite.addTest( GangliaXMLMetricImporterTest() )
suite.addTest( GangliaXMLPhysicalTopologyImporterTest() )    